#include "cookiejar.h"
#include <QtDebug>
#include <QSettings>
#include <QStringList>
#include <QList>
#include <QNetworkCookie>
#include <QNetworkAccessManager>
#include <QDateTime>

// this is needed for static members
QList< QNetworkCookie > CookieJar::sLoginCookies;

CookieJar::CookieJar() {
}

void CookieJar::setStoreDirectory( QDir dir ) {
    this->mStoreDirectory = dir;
}

QString CookieJar::activeAccount() {
    foreach ( QNetworkCookie cookie, CookieJar::sLoginCookies ) {
        if ( cookie.name() == "oAuthActiveAccount" ) {
            return cookie.value().data();
        }
    }
    return "";
}

OAuthTokenPair CookieJar::activeTokenPair() {
    return sAccounts[ activeAccount() ];
}

QMap< QString, OAuthTokenPair > CookieJar::allAccounts() {
    return sAccounts;
}

void CookieJar::accountsFromCookies() {
    QString token;
    QString secret;
    foreach ( QNetworkCookie cookie, CookieJar::sLoginCookies ) {
        // convert name and value from QByteArray to QString
        QString name = cookie.name().data();
        QString value = cookie.value().data();

        // cookie name has format: oAuthAccounts[ username ][ type ] 
        QRegExp rx( "oAuthAccounts\\[(\\w+)\\]\\[(oauth_access_token|oauth_access_token_secret)\\]" );

        // get position of regex inside cookie name
        int pos = rx.indexIn( name );
        if ( pos < 0 ) {
            continue; // some other cookie
        }

        // get username and type
        QStringList info = rx.capturedTexts();

        if ( info[ 2 ] == "oauth_access_token" ) {
            token = value;
        }
        if ( info[ 2 ] == "oauth_access_token_secret" ) {
            sAccounts.insert( info[ 1 ], OAuthTokenPair( token, value ) );
        }
    }
}
// read from storage
void CookieJar::read() {
    QFile file( "cookies.dat" );
    file.open( QIODevice::ReadOnly );

    QDataStream in( &file );
    in >> CookieJar::sLoginCookies;

    // build accounts map
    this->accountsFromCookies();
}

void CookieJar::store() {
    QFile file( "cookies.dat" );
    file.open( QIODevice::WriteOnly );

    QDataStream out( &file );
    out << CookieJar::sLoginCookies;
}

// just clears, no changes to storage
void CookieJar::clear() {
    CookieJar::sLoginCookies.clear();
}

// clears and stores
void CookieJar::clearStorage() {
    CookieJar::clear();
    CookieJar::store();
}

QList< QNetworkCookie > CookieJar::loginCookies() {
    return CookieJar::sLoginCookies;
}

// clears and loads from QNetworkAccessManager
void CookieJar::fromNetworkManager( QNetworkAccessManager * manager ) {
    this->clear();

    CookieJar::sLoginCookies = manager->cookieJar()->cookiesForUrl( QUrl( "http://www.socialwhale.com" ) );
    this->accountsFromCookies();
}

QDataStream& operator>>( QDataStream& s, QNetworkCookie & l ) {
    QByteArray name, value;
    QString domain, path;
    QDateTime expDate;

    s >> name >> value >> domain >> path >> expDate;
    QNetworkCookie cookie( name, value );
    cookie.setDomain( domain );
    cookie.setPath( path );
    cookie.setExpirationDate( expDate );

    l = cookie;

    return s;
}

QDataStream& operator<<(QDataStream& s, const QNetworkCookie& l) {
    s << l.name() << l.value() << l.domain() << l.path() << l.expirationDate();

    return s;
}
